﻿using System;
using System.Globalization;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Truextend.CoffeShop.Bussiness;
using Truextend.CoffeShop.Model;
using Truextend.Common.Data;

namespace Truextend.CoffeShop.Business.Tests
{
    [TestClass]
    public class OrderManagerTest : BaseTestClass
    {
        private Random _random;

        [TestInitialize]
        public void Initialize()
        {
            _random = new Random();
        }

        [TestMethod]
        public void CreateOrderTest()
        {
            
            ExecuteManager(uow =>
                               {
                                   ProductManager productManager = new ProductManager(uow);
                                   DetailManager detaiManager = new DetailManager(uow, productManager);
                                   OrderManager orderManager = new OrderManager(uow, detaiManager);
                                   var order = new Order()
                                                   {
                                                       UserID = 1,
                                                       UserName = "Jaime",
                                                       State = "CRE",
                                                       Title = "Rellenos del cumpleanios",
                                                       StartDate = DateTime.Now,
                                                       EndDate = DateTime.Now.AddHours(1),
                                                       ExpectedDeliveryDate = DateTime.Now.AddHours(2)
                                                   };

                                   var ids = (from p in productManager.DoQuery()
                                              select p.ProductId).Take(3).ToList();
                                   orderManager.AddOrder(order, ids);
                               });

            ExecuteOrderManager(om =>
                               {
                                   //ProductManager productManager = new ProductManager(uow);
                                   //DetailManager detaiManager = new DetailManager(uow, productManager);
                                   //OrderManager orderManager = new OrderManager(uow, detaiManager);

                                   var order = (from o in om.DoQuery()
                                                where o.Title == "Rellenos del cumpleanios"
                                                select o).First();

                                   Assert.IsNotNull(order);
                                   //Assert.AreEqual(3, order.Detail.Count);
                                   om.Delete(order);
                               });
        }

        [TestMethod]
        public void CloseOrdersTest()
        {

            List<string> allEmails = new List<string>();

            string randomName = _random.Next().ToString(CultureInfo.InvariantCulture);
            int beforeCreate = 0;
            int afterCreate = 0;
            ExecuteOrderManager(om =>
                                    {

                                        beforeCreate =
                                            om.DoQuery(new Specification<Order>(o => o.State == "INP")).Count();
                                        var order = CreateExpiredOrder(randomName);
                                    },
                                om =>
                                    {
                                        afterCreate =
                                            om.DoQuery(new Specification<Order>(o => o.State == "INP")).Count();
                                    });
            Assert.AreEqual(beforeCreate+1, afterCreate);

            int afterClose = 0;
            ExecuteOrderManager(om => om.CloseOrderReception(allEmails),
                                om =>
                                    {
                                        afterClose =
                                            om.DoQuery(new Specification<Order>(o => o.State == "INP")).Count();
                                        var order =
                                            om.DoQuery(
                                                new Specification<Order>(
                                                    o => o.Title == randomName && o.State == "COM")).Single();
                                        Assert.IsNotNull(order);
                                    });
            Assert.AreEqual(afterCreate - 1, afterClose);
        }

        private Order CreateExpiredOrder(string title)
        {
            var order = new Order()
            {
                UserID = 1,
                UserName = "Jaime",
                State = "INP",
                Title = title,
                StartDate = DateTime.Now.AddMinutes(5), //Expired Order
                EndDate = DateTime.Now,
                ExpectedDeliveryDate = DateTime.Now.AddMinutes(20),
                Drink = true
            };
            ExecuteOrderManager(om => om.Add(order));
            return order;
        }

        private void ExecuteOrderManager(Action<OrderManager> coreMethod, Action<OrderManager> postCommit=null)
        {
            OrderManager orderManager = null;
            ExecuteManager(uow =>
            {
                ProductManager productManager = new ProductManager(uow);
                DetailManager detaiManager = new DetailManager(uow, productManager);
                orderManager = new OrderManager(uow, detaiManager);

                coreMethod(orderManager);
            });
            if (postCommit != null) postCommit(orderManager);
        }
    }
}
